% Chakram is a subproject of Hexena - Haskell Executable Analyser
% License:			GPL-3
% Maintainer:		Montez Fitzpatrick
% Stability:		Experimental
% Portability:		GHC
% Module:			Hexena.Codec.Parser.LoadConfigDirectory

LoadConfig Directory Format

All image files that LoadConfig symbols, including virtually all EXE files 
have an '.idata' section

\begin{code}
module Hexena.Codec.Parser.LoadConfigDirectory (parseLoadConfigDir) where

import Data.Binary.Get

import Data.Int (Int64)
import Data.Word
import Data.Label -- Needs 'fclabels

-- import Control.Monad (replicateM, liftM2)

import Hexena.Data.LoadConfigDirectory (LoadConfigDirectory(..))
import Hexena.Data.LoadConfigDirectory.X86 (X86(..))
import Hexena.Data.LoadConfigDirectory.AMD64 (AMD64(..))
import Hexena.Internal.Constants


parseLoadConfigDir :: (Eq a, Num a) => a -> Get LoadConfigDirectory
parseLoadConfigDir instructionSet = case instructionSet of
    iMAGE_FILE_MACHINE_I386  -> doAsPE
	iMAGE_FILE_MACHINE_AMD64 -> doAsPEplus
    otherwise				 -> error "unsupported Instruction Set"
  where
    doAsPE = do
        lcd_size <- getWord32le
        lcd_timeDateStamp <- getWord32le
        lcd_majorVersion <- getWord16le
        lcd_minorVersion <- getWord16le
        lcd_globalFlagsClear <- getWord32le
        lcd_globalFlagsSet <- getWord32le
        lcd_critSectDefTimeout <- getWord32le
        lcd_deCommitFBThreshd32 <- getWord32le
        lcd_deCommitTFThreshd32 <- getWord32le
        lcd_lockPreTbl32 <- getWord32le
        lcd_maxAllocSz32 <- getWord32le
        lcd_virtMemThreshd32 <- getWord32le
        lcd_procHeapFlags <- getWord32le
        lcd_procAffinityMask32 <- getWord32le
        lcd_cSDVersion <- getWord16le
        lcd_reserved1 <- getWord16le
        lcd_editList32 <- getWord32le
        lcd_securityCookie32 <- getWord32le
        lcd_sEHandlerTbl32 <- getWord32le
        lcd_sEHandlerCnt32 <- getWord32le

        return $ X86 lcd_size lcd_timeDateStamp lcd_majorVersion lcd_minorVersion lcd_globalFlagsClear lcd_globalFlagsSet lcd_critSectDefTimeout lcd_deCommitFBThreshd32 lcd_deCommitTFThreshd32 lcd_lockPreTbl32 lcd_maxAllocSz32 lcd_virtMemThreshd32 lcd_procHeapFlags lcd_procAffinityMask32 lcd_cSDVersion lcd_reserved1 lcd_editList32 lcd_securityCookie32 lcd_sEHandlerTbl32 lcd_sEHandlerCnt32 

    doAsPEplus = do
        lcd_size <- getWord32le
        lcd_timeDateStamp <- getWord32le
        lcd_majorVersion <- getWord16le
        lcd_minorVersion <- getWord16le
        lcd_globalFlagsClear <- getWord32le
        lcd_globalFlagsSet <- getWord32le
        lcd_critSectDefTimeout <- getWord32le
        lcd_deCommitFBThreshd64 <- getWord64le
        lcd_deCommitTFThreshd64 <- getWord64le
        lcd_lockPreTbl64 <- getWord64le
        lcd_maxAllocSz64 <- getWord64le
        lcd_virtMemThreshd64 <- getWord64le
        lcd_procAffinityMask64 <- getWord64le
        lcd_procHeapFlags <- getWord32le
        lcd_cSDVersion <- getWord16le
        lcd_reserved1 <- getWord16le
        lcd_editList64 <- getWord64le
        lcd_securityCookie64 <- getWord64le
        lcd_sEHandlerTbl64 <- getWord64le
        lcd_sEHandlerCnt64 <- getWord64le

        return $ AMD64 lcd_size lcd_timeDateStamp lcd_majorVersion lcd_minorVersion lcd_globalFlagsClear lcd_globalFlagsSet lcd_critSectDefTimeout lcd_deCommitFBThreshd64 lcd_deCommitTFThreshd64 lcd_lockPreTbl64 lcd_maxAllocSz64 lcd_virtMemThreshd64 lcd_procAffinityMask64 lcd_procHeapFlags lcd_cSDVersion lcd_reserved1 lcd_editList64 lcd_securityCookie64 lcd_sEHandlerTbl64 lcd_sEHandlerCnt64 
\end{code}
